package dao

import (
	"fmt"
	"runtime"
	"shop/common/log"
	"shop/config"
	"shop/utils/result"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
)

var mysqlCli *gorm.DB

func InitMysql() {
	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True",
		config.Conf.MysqlUsername, config.Conf.MysqlPassword, config.Conf.MysqlAddress, config.Conf.MysqlDBName)
	logLevel := logger.Info
	if config.IsProdEnv() {
		logLevel = logger.Warn
	}
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "",
			SingularTable: true,
		},
		Logger: logger.New(log.Config.Logger, logger.Config{
			SlowThreshold:             time.Second,
			IgnoreRecordNotFoundError: true,
			LogLevel:                  logLevel,
		}),
	})
	if err != nil {
		panic(fmt.Sprintf("fail to connect mysql, err:%v", err))
	}

	mysqlCli = db
	sqlDB, err := db.DB()
	if err != nil {
		panic("connect db server failed.")
	}
	log.Infof("success connect mysql, address=%s, dbName=%s", config.Conf.MysqlAddress, config.Conf.MysqlDBName)
	// 配置数据库连接池
	sqlDB.SetMaxIdleConns(5 + runtime.NumCPU())
	sqlDB.SetMaxOpenConns(runtime.NumCPU() * 10)
	sqlDB.SetConnMaxLifetime(time.Minute * 10)
}

func GetDB() *gorm.DB {
	return mysqlCli
}

func GetTx() *gorm.DB {
	return mysqlCli.Begin()
}

// CommitByResult 提交事务
/*
	使用方式
	tx := dao.GetTx()
	defer func() {
		res = dao.CommitByResult(res, tx)
	}()
*/
func CommitByResult(res *result.Result, tx *gorm.DB) *result.Result {
	if res.Code == result.ErrCodeOk {
		if err := tx.Commit().Error; err != nil {
			log.Errorf("事务提交失败, err: %v", err)
			res = result.Fail("事务提交失败")
		}
	} else {
		tx.Rollback()
	}
	return res
}
